<?php
/**
 * Created by PhpStorm
 * User: Jhinwy
 * Date: 4/15/24
 * Time: 4:29 PM
 */

namespace app\common\service\media;

use app\api\service\RecycleReportService;
use app\common\model\callback\OrderCallback;
use app\common\model\click\BdClick;
use app\common\model\click\KsClick;
use app\common\model\click\UcClick;
use app\common\model\click\VivoClick;
use app\common\model\media\Media;
use app\common\model\media_account\MediaAccount;
use app\common\model\promotion\PromotionLink;
use app\common\model\quickapp\Quickapp;
use app\common\model\recycle_report\RecycleReportDetail;
use app\common\service\TagsService;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use think\Collection;
use app\common\model\click\CpaClick;
use think\facade\Log;

/**
 *
 *
 * https://event-manager.oceanengine.com/docs/8650/quickapp/
 *
 * Class MediaService
 * @package app\common\service\media
 */
class MediaService
{
    protected static $jlUrl   = 'https://analytics.oceanengine.com/api/v2/conversion';
    protected static $ksUrl   = 'http://ad.partner.gifshow.com/track/activate?callback=';
    protected static $vivoUrl = 'https://marketing-api.vivo.com.cn/openapi/v1/advertiser/behavior/upload';

    protected static $headers = [
        'Content-Type' => 'application/json',
    ];


    // 巨量 type 注册， 激活，付费，关键行为
    const JL_TYPE_REGISTER       = 'active_register';
    const JL_TYPE_ACTIVE         = 'active';
    const JL_TYPE_PAYMENT        = 'active_pay';
    const JL_TYPE_GAME_ADDICTION = 'game_addiction';

    // UC type 67打开  68加桌  69付费
    const UC_TYPE_ACTIVE      = 67;
    const UC_TYPE_ADD_DESKTOP = 68;
    const UC_TYPE_PAYMENT     = 69;
    const UC_TYPE_PAY         = 1000;

    // 快手 event_type  1激活  2注册  3付费
    const KS_TYPE_ACTIVE   = 1;
    const KS_TYPE_REGISTER = 2;
    const KS_TYPE_PAYMENT  = 3;

    // 百度 event_type  1应用调起  2加桌  3付费阅读 4关键行为
    const BD_TYPE_ACTIVE      = 'activate';
    const BD_TYPE_DEEPLINK    = 'deeplink';
    const BD_TYPE_ADD_DESKTOP = 'add_to_desktop';
    const BD_TYPE_PAYMENT     = 'pay_to_read';
    const BD_TYPE_ACTION      = 'key_action';


    // VIVO type  1激活  2注册  3加桌  4付费
    const VIVO_TYPE_ACTIVE      = 'ACTIVATION';
    const VIVO_TYPE_REGISTER    = 'REGISTER';
    const VIVO_TYPE_ADD_DESKTOP = 'ADD_SCREEN';
    const VIVO_TYPE_PAYMENT     = 'PAY';

    /**
     * 匹配头条-巨量引擎 callback_param
     *
     * @param $userCallback
     * @param $promotion_link_id
     * @return mixed|string
     */
    public static function getJlCallbackParam($userCallback, $promotion_link_id)
    {
        if (!$userCallback || !$promotion_link_id) {

            return '';
        }
        // 通过ip+ua等匹配检测链接  表里缓存>oa_id>imei>ip_ua>ip
        if (isset($userCallback->callback_param) && $userCallback->callback_param != '') {
            return $userCallback->callback_param;
        } else {
            $res = new Collection([]);
            if ($userCallback->oa_id && $userCallback->oa_id != '00000000-0000-0000-0000-000000000000') {
                $res = CpaClick::where(['promotion_link_id' => $promotion_link_id, 'oaid' => $userCallback->oa_id])->order('id', 'desc')->findOrEmpty();
            }

            if ($res->isEmpty()) {
                if ($userCallback->imei != '') {
                    $res = CpaClick::where(['promotion_link_id' => $promotion_link_id, 'imei' => $userCallback->imei])->order('id', 'desc')->findOrEmpty();
                }
            }
            if ($res->isEmpty()) {
                if ($userCallback->ip_ua != '') {
                    $res = CpaClick::where(['promotion_link_id' => $promotion_link_id, 'ipua_md5' => $userCallback->ip_ua])->order('id', 'desc')->findOrEmpty();
                }
            }
            //ip匹配查询近7天数据
            if ($res->isEmpty()) {
                if ($userCallback->login_ip != '') {
                    $time = date('Y-m-d H:i:s', strtotime('-7 days'));
                    $res  = CpaClick::where(['promotion_link_id' => $promotion_link_id, 'ip' => $userCallback->login_ip])->where('created_at', '>=', $time)->order('id', 'desc')->findOrEmpty();
                }
            }

            if (!$res->isEmpty() && $res->callback_param != null) {
                dump('存储callback_param');
                //                $userCallback->callback_param = $res->callback_param;
                //                $userCallback->save();
                return $res->callback_param;
            } else {
                return '';
            }

        }
    }


    /**
     * 获取UC回传标识
     *
     * @param $userCallback
     * @param $promotion_link_id
     * @return mixed|string
     */
    public static function getUcCallback($userCallback, $promotion_link_id)
    {
        if (!$userCallback || !$promotion_link_id) {

            return '';
        }
        // 匹配o_id
        if (($userCallback->oa_id ?? '') && $userCallback->oa_id != '00000000-0000-0000-0000-000000000000') {
            if ($callbackUrl = UcClick::where(['promotion_link_id' => $promotion_link_id, 'oaid' => $userCallback->oa_id])->order('id', 'desc')->value('callback_url')) {

                return $callbackUrl;
            }
        }

        // 匹配imei
        if ($userCallback->imei ?? '') {
            if ($callbackUrl = UcClick::where(['promotion_link_id' => $promotion_link_id, 'imei' => $userCallback->imei])->order('id', 'desc')->value('callback_url')) {

                return $callbackUrl;
            }
        }

        // 匹配ip_ua
        if ($userCallback->ip_ua != '') {
            if ($callbackUrl = UcClick::where(['promotion_link_id' => $promotion_link_id, 'ipua' => $userCallback->ip_ua])->order('id', 'desc')->value('callback_url')) {

                return $callbackUrl;
            }
        }

        // ip匹配查询近7天数据
        if ($userCallback->login_ip != '') {
            $time = strtotime('-7 days');
            if ($callbackUrl = UcClick::where(['promotion_link_id' => $promotion_link_id, 'ip' => $userCallback->login_ip])->where('create_time', '>=', $time)->order('id', 'desc')->value('callback_url')) {

                return $callbackUrl;
            }
        }

        return '';
    }


    /**
     * 匹配快手callback
     *
     * @param $userCallback
     * @param $promotion_link_id
     * @return mixed|string
     */
    public static function getKsCallback($userCallback, $promotion_link_id)
    {
        if (!$userCallback || !$promotion_link_id) {

            return '';
        }
        $ksCallback = $userCallback->ks_callback ?? '';
        if ($ksCallback) {

            return $ksCallback;
        }

        // 匹配o_id
        if (($userCallback->oa_id ?? '') && $userCallback->oa_id != '00000000-0000-0000-0000-000000000000') {
            if ($ksCallback = KsClick::where(['promotion_link_id' => $promotion_link_id, 'oaid' => $userCallback->oa_id])->order('id', 'desc')->value('callback')) {

                return $ksCallback;
            }
        }

        // 匹配imei
        if ($userCallback->imei ?? '') {
            if ($ksCallback = KsClick::where(['promotion_link_id' => $promotion_link_id, 'imei' => $userCallback->imei])->order('id', 'desc')->value('callback')) {

                return $ksCallback;
            }
        }

        // 匹配ip_ua
        if ($userCallback->ip_ua != '') {
            if ($ksCallback = KsClick::where(['promotion_link_id' => $promotion_link_id, 'ipua' => $userCallback->ip_ua])->order('id', 'desc')->value('callback')) {

                return $ksCallback;
            }
        }

        // ip匹配查询近7天数据
        if ($userCallback->login_ip != '') {
            $time = strtotime('-7 days');
            if ($ksCallback = KsClick::where(['promotion_link_id' => $promotion_link_id, 'ip' => $userCallback->login_ip])->where('create_time', '>=', $time)->order('id', 'desc')->value('callback')) {

                return $ksCallback;
            }
        }

        return '';
    }


    /**
     * 匹配百度callback
     *
     * @param $userCallback
     * @param $promotion_link_id
     * @return array
     */
    public static function getBdCallback($userCallback, $promotion_link_id)
    {
        if (!$userCallback || !$promotion_link_id) {

            return ['', ''];
        }
        // 匹配o_id
        if (($userCallback->oa_id ?? '') && $userCallback->oa_id != '00000000-0000-0000-0000-000000000000') {
            if ($callbackUrl = BdClick::where(['promotion_link_id' => $promotion_link_id, 'oaid' => $userCallback->oa_id])->order('id', 'desc')->value('callback_url')) {

                return ['oaid', $callbackUrl];
            }
        }

        // 匹配imei
        if ($userCallback->imei ?? '') {
            if ($callbackUrl = BdClick::where(['promotion_link_id' => $promotion_link_id, 'imei_md5' => md5($userCallback->imei)])->order('id', 'desc')->value('callback_url')) {

                return ['imei', $callbackUrl];
            }
        }

        // 匹配ip_ua
        if ($userCallback->ip_ua != '') {
            if ($callbackUrl = BdClick::where(['promotion_link_id' => $promotion_link_id, 'ipua' => $userCallback->ip_ua])->order('id', 'desc')->value('callback_url')) {

                return ['ip', $callbackUrl];
            }
        }

        // ip匹配查询近7天数据
        if ($userCallback->login_ip != '') {
            $time = strtotime('-7 days');
            if ($callbackUrl = BdClick::where(['promotion_link_id' => $promotion_link_id, 'ip' => $userCallback->login_ip])->where('create_time', '>=', $time)->order('id', 'desc')->value('callback_url')) {

                return ['ip', $callbackUrl];
            }
        }

        return ['', ''];
    }


    /**
     * 获取vivo点击详情
     *
     * @param $userCallback
     * @param $promotion_link_id
     * @return VivoClick|array|mixed|Collection|\think\Model
     */
    public static function getVivoClick($userCallback, $promotion_link_id)
    {
        if (!$userCallback || !$promotion_link_id) {

            return '';
        }
        // 匹配o_id
        if (($userCallback->oa_id ?? '') && $userCallback->oa_id != '00000000-0000-0000-0000-000000000000') {
            $click = VivoClick::where(['promotion_link_id' => $promotion_link_id, 'oaid' => $userCallback->oa_id])->order('id', 'desc')->findOrEmpty();
            if (!$click->isEmpty()) {
                return $click;
            }
        }

        // 匹配imei
        if ($userCallback->imei ?? '') {
            $click = VivoClick::where(['promotion_link_id' => $promotion_link_id, 'imei' => $userCallback->imei])->order('id', 'desc')->findOrEmpty();
            if (!$click->isEmpty()) {

                return $click;
            }
        }

        // ip匹配查询近7天数据
        if ($userCallback->login_ip != '') {
            $time  = strtotime('-7 days');
            $click = VivoClick::where(['promotion_link_id' => $promotion_link_id, 'ip' => md5($userCallback->login_ip)])->where('create_time', '>=', $time)->order('id', 'desc')->findOrEmpty();
            if (!$click->isEmpty()) {

                return $click;
            }
        }

        return new Collection([]);
    }

    /**
     * 获取广告计划ID
     *
     * @param $message
     * @param $userCallback
     */
    public static function getAdID($message, $userCallback, $source)
    {
        $result = [];
        switch ($source) {
            case Media::SOURCE_JL :
                $callback_param = self::getJlCallbackParam($userCallback, $message['promotion_link_id']);
                if (!empty($callback_param)) {
                    $click = CpaClick::where('callback_param', $callback_param)->findOrEmpty();
                    if (!$click->isEmpty()) {
                        $result['ad_id']      = $click->promotion_id??0;
                        $result['project_id'] = $click->project_id??0;
                        $result['advertising_id'] = $click->aid??0;
                    }
                }
                break;
            case Media::SOURCE_UC :
                $callbackUrl = self::getUcCallback($userCallback, $message['promotion_link_id']);
                if ($callbackUrl) {
                    //                    $ad_id = UcClick::where('callback_url', $callbackUrl)->value('aid') ?? 0;
                    $click = UcClick::where('callback_url', $callbackUrl)->findOrEmpty();
                    if (!$click->isEmpty()) {
                        $result['ad_id']      = $click->cid??0;//创意ID
                        $result['project_id'] = $click->gid??0;//广告组
                        $result['advertising_id'] = $click->aid??0;//广告ID
                    }
                }
                break;
            case Media::SOURCE_KS :
                $ksCallback = self::getKsCallback($userCallback, $message['promotion_link_id']);
                if ($ksCallback) {
                    //                    $ad_id = KsClick::where('callback', $ksCallback)->value('aid') ?? 0;
                    $click = KsClick::where('callback', $ksCallback)->findOrEmpty();
                    if (!$click->isEmpty()) {
                        $result['ad_id']      = $click->cid??0;
                        $result['project_id'] = $click->aid??0;
                        $result['advertising_id'] = $click->did??0;//广告ID
                    }
                }
                break;
            case Media::SOURCE_BD :
                list($type, $callbackUrl) = self::getBdCallback($userCallback, $message['promotion_link_id']);
                if ($type && $callbackUrl) {
                    //                    $ad_id = BdClick::where('callback_url', $callbackUrl)->value('pid') ?? 0;
                    $click = BdClick::where('callback_url', $callbackUrl)->findOrEmpty();
                    if (!$click->isEmpty()) {
                        $result['ad_id']      = $click->pid;
                        $result['project_id'] = $click->aid;
                    }
                }
                break;
            case Media::SOURCE_VIVO :
                $click = self::getVivoClick($userCallback, $message['promotion_link_id']);
                if (!$click->isEmpty()) {
                    //                    $ad_id = $click->campaign_id;
//                    $result['ad_id']      = $click->campaign_id;
//                    $result['project_id'] = $click->creative_id;

                    $result['ad_id']      = $click->creative_id??0;//创意ID
                    $result['project_id'] = $click->creative_id??0;//广告组
                    $result['advertising_id'] = $click->adid??0;//广告ID
                }
                break;
        }
        return $result;
    }


    /**
     * 注册
     *
     * @param $message
     * @param $userCallback
     */
    public static function register($message, $userCallback, $source)
    {
        switch ($source) {
            case Media::SOURCE_JL :
                $callback_param = self::getJlCallbackParam($userCallback, $message['promotion_link_id']);
                if (!empty($callback_param)) {
                    $result = self::JlReturn($message, $callback_param, self::JL_TYPE_REGISTER);
                    if ($result['code'] != 0) {
                        dump("巨量用户注册回传失败 用户ID-" . $message['user_id']);
                    } else {
                        dump("巨量用户注册回传成功 用户ID-" . $message['user_id']);
                    }
                }
                break;
            case Media::SOURCE_UC :
                $callbackUrl = self::getUcCallback($userCallback, $message['promotion_link_id']);
                if ($callbackUrl) {
                    self::UcReturn($message, $callbackUrl, self::UC_TYPE_ACTIVE);
                }
                break;
            case Media::SOURCE_KS :
                $ksCallback = self::getKsCallback($userCallback, $message['promotion_link_id']);
                if ($ksCallback) {
                    self::KsReturn($message, $ksCallback, self::KS_TYPE_REGISTER);
                }
                break;
            case Media::SOURCE_BD :
                list($type, $callbackUrl) = self::getBdCallback($userCallback, $message['promotion_link_id']);
                if ($type && $callbackUrl) {
                    self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_ACTIVE);
                }
                break;
            case Media::SOURCE_VIVO :
                $click = self::getVivoClick($userCallback, $message['promotion_link_id']);
                if (!$click->isEmpty()) {
                    self::VivoReturn($message, $click, self::VIVO_TYPE_REGISTER);
                }
                break;
        }
    }


    /**
     * 激活
     *
     * @param $message
     * @param $userCallback
     */
    public static function active($message, $userCallback, $source)
    {
        switch ($source) {
            case Media::SOURCE_JL :
                $callback_param = self::getJlCallbackParam($userCallback, $message['promotion_link_id']);
                if (!empty($callback_param)) {
                    $result = self::JlReturn($message, $callback_param, self::JL_TYPE_ACTIVE);
                    if ($result['code'] != 0) {
                        dump("巨量用户激活回传失败 用户ID-" . $message['user_id']);
                    } else {
                        dump("巨量用户激活回传成功 用户ID-" . $message['user_id']);
                    }
                }
                break;
            case Media::SOURCE_UC :
                $callbackUrl = self::getUcCallback($userCallback, $message['promotion_link_id']);
                if ($callbackUrl) {
                    self::UcReturn($message, $callbackUrl, self::UC_TYPE_ACTIVE);
                }
                break;
            case Media::SOURCE_KS :
                $ksCallback = self::getKsCallback($userCallback, $message['promotion_link_id']);
                if ($ksCallback) {
                    self::KsReturn($message, $ksCallback, self::KS_TYPE_ACTIVE);
                }
                break;
            case Media::SOURCE_BD :
                list($type, $callbackUrl) = self::getBdCallback($userCallback, $message['promotion_link_id']);
                if ($type && $callbackUrl) {
                    self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_ACTIVE);
                    self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_DEEPLINK);
                }
                break;
            case Media::SOURCE_VIVO :
                $click = self::getVivoClick($userCallback, $message['promotion_link_id']);
                if (!$click->isEmpty()) {
                    self::VivoReturn($message, $click, self::VIVO_TYPE_ACTIVE);
                }
                break;
        }
    }


    /**
     * 加桌
     *
     * @param $message
     * @param $userCallback
     */
    public static function addDesktop($message, $userCallback, $source)
    {
        switch ($source) {
            case Media::SOURCE_JL :
                $callback_param = self::getJlCallbackParam($userCallback, $message['promotion_link_id']);
                if (!empty($callback_param)) {
                    $result = self::JlReturn($message, $callback_param, self::JL_TYPE_ACTIVE);
                    if ($result['code'] != 0) {
                        dump("巨量用户加桌回传失败 用户ID-" . $message['user_id']);
                    } else {
                        // 回传成功
                        dump("巨量用户加桌回传成功 用户ID-" . $message['user_id']);
                    }
                }
                break;
            case Media::SOURCE_UC :
                $callbackUrl = self::getUcCallback($userCallback, $message['promotion_link_id']);
                if ($callbackUrl) {
                    self::UcReturn($message, $callbackUrl, self::UC_TYPE_ADD_DESKTOP);
                }
                break;
            case Media::SOURCE_KS :
                $ksCallback = self::getKsCallback($userCallback, $message['promotion_link_id']);
                if ($ksCallback) {
                    self::KsReturn($message, $ksCallback, self::KS_TYPE_ACTIVE);
                }
                break;
            case Media::SOURCE_BD :
                list($type, $callbackUrl) = self::getBdCallback($userCallback, $message['promotion_link_id']);
                if ($type && $callbackUrl) {
                    self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_ADD_DESKTOP);
                }
                break;
            case Media::SOURCE_VIVO :
                $click = self::getVivoClick($userCallback, $message['promotion_link_id']);
                if (!$click->isEmpty()) {
                    self::VivoReturn($message, $click, self::VIVO_TYPE_ADD_DESKTOP);
                }
                break;
        }
    }


    /**
     * 付费回传
     *
     * @param $message
     * @param $userCallback
     * @param $user
     * @param $order
     * @param $source
     * @param bool $isHc
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function payment($message, $userCallback, $user, $order, $source, $returnRule, $isHc = true)
    {

        $promotionLink             = PromotionLink::where('id', $user->promotion_link_id)->findOrEmpty();
        $data                      = [];
        $promotionLinkId           = $user->promotion_link_id ?? 0;
        $data['order_id']          = $message['order_id'];
        $data['admin_id']          = $promotionLink->admin_id ?? 0;
        $data['platform']          = $order->platform;
        $data['user_id']           = $order->user_id;
        $data['is_new_user']       = $user->is_new_user;
        $data['register_time']     = strtotime($user->register_time);
        $data['promotion_link_id'] = $promotionLinkId;
        $data['return_rule_id']    = $returnRule->id ?? 0;
        $data['media_account_id']  = MediaAccount::where('promotion_link_id', $promotionLinkId)->value('id') ?? 0;
        $data['recharge_times']    = $user->paynum;
        $data['dyeing_time']       = $userCallback->dyeing_time ?? 0;
        $data['return_status']     = 0; //默认未回传
        $data['match_status']      = 0; // 匹配状态
//        $data['ad_id']             = $promotionLink->ad_id ?? 0; // 广告创意ID
//        $data['project_id']        = $promotionLink->project_id ?? 0; // 广告组ID
//        $data['advertising_id']    = $promotionLink->advertising_id ?? 0; // 广告ID
        if ($user->promotion_link_id>0){
            dump("订单绑定监测链接 订单ID" . $message['order_id']);
            $message['promotion_link_id'] = $user->promotion_link_id;
            $adId = MediaService::getAdId($message, $userCallback,$order['source'] ?? 0);
            $data['ad_id'] = $adId['ad_id']??0;
            $data['project_id'] = $adId['project_id']??0;
            $data['advertising_id'] = $adId['advertising_id']??0;
        }

        if ($isHc) {
            switch ($source) {
                case Media::SOURCE_JL :
                    $callback_param = self::getJlCallbackParam($userCallback, $promotionLinkId);
                    if ($callback_param) {
                        $data['match_status'] = 1;
                        $click                = CpaClick::where('callback_param', $callback_param)->findOrEmpty();
                        $data['ad_id']        = $click->promotion_id ?? 0;
                        $data['ad_name']      = $click->promotion_name ?? '';
                        $data['project_id']   = $click->project_id ?? 0;
                        $data['project_name'] = $click->project_name ?? '';
                        $data['advertising_id']   = $click->aid ?? 0;
                        $money                = $order['money'] * 100;
                        $result               = self::JlReturn($message, $callback_param, self::JL_TYPE_PAYMENT, $money);
                        if ($result['code'] == 0) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("巨量用户付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("巨量用户付费订单回传失败 订单ID" . $message['order_id']);
                        }
                    } else {
                        dump("未匹配到用户 订单ID" . $message['order_id']);
                    }
                    break;
                case Media::SOURCE_UC :
                    $callbackUrl = self::getUcCallback($userCallback, $user->promotion_link_id);
                    dump("UC用户监测链接1 订单ID" . $message['order_id']);
                    if ($callbackUrl) {
//                        dump("UC用户监测链接2 订单ID" . $message['order_id']);
//                        $click = UcClick::where(['callback_url' => $callbackUrl])->order('id', 'desc')->findOrEmpty();
//                        if (!$click->isEmpty()){
//                            dump("UC用户监测链接3 订单ID" . $message['order_id'].'aid:'.$click->aid);
//                            $data['ad_id']             = $click->cid ?? 0; // 广告创意ID
//                            $data['project_id']        = $click->gid ?? 0; // 广告组ID
//                            $data['advertising_id']    = $click->aid ?? 0; // 广告ID
//                        }
                        $data['match_status'] = 1;
                        $result               = self::UcReturn($message, $callbackUrl, self::UC_TYPE_PAYMENT);
                        if ($result) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("UC用户快应用付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("UC用户快应用付费订单回传失败 订单ID" . $message['order_id']);
                        }
                        $payResult = self::UcReturn($message, $callbackUrl, self::UC_TYPE_PAY);
                        if ($payResult) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("UC用户付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("UC用户付费订单回传失败 订单ID" . $message['order_id']);
                        }
                    }
                    break;
                case Media::SOURCE_KS :
                    $ksCallback = self::getKsCallback($userCallback, $user->promotion_link_id);
                    if ($ksCallback) {
                        $data['match_status'] = 1;
                        $click                = KsClick::where(['promotion_link_id' => $user->promotion_link_id, 'callback' => $ksCallback])->order('id', 'desc')->findOrEmpty();
                        if (!$click->isEmpty()) {
                            $data['project_id'] = $click->aid ?? '';
                        }
                        $money  = $order['money'];
                        $result = self::KsReturn($message, $ksCallback, self::KS_TYPE_PAYMENT, $money);
                        if ($result) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("快手用户付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("快手用户付费订单回传失败 订单ID" . $message['order_id']);
                        }
                    }
                    break;
                case Media::SOURCE_BD :
                    list($type, $callbackUrl) = self::getBdCallback($userCallback, $user->promotion_link_id);
                    if ($type && $callbackUrl) {
                        $data['match_status'] = 1;
                        $money                = $order['money'];
                        $result               = self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_PAYMENT, $money);
                        if ($result) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("百度用户付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("百度用户付费订单回传失败 订单ID" . $message['order_id']);
                        }
                    }
                    break;
                case Media::SOURCE_VIVO :
                    $click = self::getVivoClick($userCallback, $user->promotion_link_id);
                    if (!$click->isEmpty()) {
                        $data['match_status'] = 1;
                        $money                = $order['money'];
                        $result               = self::VivoReturn($message, $click, self::VIVO_TYPE_PAYMENT, $money);
                        if ($result) {
                            // 回传成功
                            $data['return_status']  = 1;
                            $data['reporting_time'] = time();
                            dump("VIVO用户付费订单回传成功 订单ID" . $message['order_id']);
                        } else {
                            $data['return_status'] = 2;
                            dump("VIVO用户付费订单回传失败 订单ID" . $message['order_id']);
                        }
                    }
                    break;
            }
        } else {
            $data['return_status'] = 3;//被扣除
            dump("用户订单扣除，未回传 订单ID-" . $message['order_id']);
        }

        //订单回传插入
        OrderCallback::create($data);
        //订单报表统计
        RecycleReportService::countReport($order);
        //用户上报状态更新
        if ($data['return_status'] == 1 && $userCallback->is_report == 0) {
            $userCallback->is_report = 1;
            $userCallback->save();
        }
        //更新报表详情
        if ($promotionLinkId > 0) {
            dump("更新订单报表明细 订单ID-" . $message['order_id']);
            $date        = date('Y-m-d', time());
            $dyeing_date = date('Y-m-d', $userCallback->dyeing_time);
            $diff        = abs(strtotime($date) - strtotime($dyeing_date));
            // 将差值转换为天数 然后+1
            $day = floor($diff / (60 * 60 * 24)) + 1;
            //根据推广链，染色日期，天数 3个参数判断数据是否存在，存在就更新，不存在插入
            $recycleReportDetail = RecycleReportDetail::where(['promotion_link_id' => $promotionLinkId, 'day' => $day, 'count_date' => $dyeing_date])->findOrEmpty();
            if ($recycleReportDetail->isEmpty()) {
                $recycleReportDetailData = [
                    'promotion_link_id' => $promotionLinkId,
                    'day'               => $day,
                    'count_date'        => $dyeing_date,
                    'recharge_money'    => $order->money,
                ];
                RecycleReportDetail::create($recycleReportDetailData);
            } else {
                $recycleReportDetail->recharge_money += $order->money;
                $recycleReportDetail->save();
            }
        }
        //更新用户标签
        TagsService::matchTags(1, $user, $order);
    }


    /**
     * 关键行为
     *
     * @param $message
     * @param $userCallback
     * @param $order
     * @param $source
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function keyAction($message, $userCallback, $order, $source)
    {
        switch ($source) {
            case Media::SOURCE_JL :
                $callback_param = self::getJlCallbackParam($userCallback, $message['promotion_link_id']);
                if (!empty($callback_param)) {
                    $money = $order['money'] * 100;
                    self::JlReturn($message, $callback_param, self::JL_TYPE_GAME_ADDICTION, $money);
                }
                break;
            case Media::SOURCE_BD :
                list($type, $callbackUrl) = self::getBdCallback($userCallback, $message['promotion_link_id']);
                if ($type && $callbackUrl) {
                    self::BdReturn($message, $type, $callbackUrl, self::BD_TYPE_ACTION);
                }
                break;
        }
    }


    /**
     * 巨量回传
     *
     * @param $message
     * @param $callbackParam
     * @return bool|mixed|string
     */
    public static function JlReturn($message, $callbackParam, $type, $orderMoney = 0)
    {
        $msectime = msectime();

        $content = [
            'event_type' => $type,
            'context'    => [
                'ad' => ['callback' => $callbackParam]
            ],
            'timestamp'  => $msectime
        ];
        if ($type == self::JL_TYPE_PAYMENT) {
            $content['properties'] = [
                'pay_amount' => $orderMoney * 100
            ];
        }
        Log::write('巨量回传：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . ': ' . json_encode($content) . ' 请求参数');
        $result = curlPost(self::$jlUrl, $content);
        $result = json_decode($result, true);
        Log::write('巨量回传：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . ': ' . json_encode($result) . ' 返回参数');

        return $result;
    }


    /**
     * UC回传
     *
     * @param $sid
     * @param $type
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function UcReturn($message, $callbackUrl, $type)
    {
        try {
            $microtime = msectime();
            $url       = $callbackUrl . '&type=' . $type . '&event_time=' . $microtime;
            $client    = new Client();
            $result    = $client->get($url);
            if ($result->getStatusCode() == 200) {
                $contents = $result->getBody()->getContents();
                $data     = json_decode($contents, true);
                if ($data['status'] == 0) {
                    Log::write('UC回传成功：用户' . $type . '参数打印 用户ID-' . $message['user_id']);

                    return true;
                } else {
                    throw new \Exception('请求UC失败');
                }
            }

            return false;
        } catch (\Exception $exception) {
            Log::write('UC回传失败：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . '===>' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 快手回传
     *
     * @param $message
     * @param $callback
     * @param $type
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function KsReturn($message, $callback, $type, $orderMoney = 0)
    {
        try {
            $event_time = msectime();
            $client     = new Client();
            if (!strstr($callback, 'http:')) {
                $callback = self::$ksUrl . $callback;
            }
            $callback .= '&event_type=' . $type . '&event_time=' . $event_time;
            if ($type == self::KS_TYPE_PAYMENT) {
                $callback .= '&purchase_amount=' . round($orderMoney, 2);
            }
            $result = $client->get($callback);
            if ($result->getStatusCode() == 200) {
                $contents = $result->getBody()->getContents();
                $data     = json_decode($contents, true);
                if ($data['result'] == 1) {
                    Log::write('快手回传成功：用户' . $type . '参数打印 用户ID-' . $message['user_id']);

                    return true;
                } else {
                    throw new \Exception('请求快手回传失败');
                }
            }

            return false;
        } catch (\Exception $exception) {
            Log::write('快手回传失败：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . '===>' . $exception->getMessage());

            return false;
        }
    }


    /**
     * 百度回传
     *
     * @param $message
     * @param $callback
     * @param $type
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function BdReturn($message, $callbackType, $callback, $type, $orderMoney = 0)
    {
        try {
            $url = str_replace('{{ATYPE}}', $type, $callback);
            $url = str_replace('{{AVALUE}}', $orderMoney * 100, $url);
            $url .= '&join_type=' . $callbackType;

            $client = new Client();
            $result = $client->get($url);
            if ($result->getStatusCode() == 200) {
                $contents = $result->getBody()->getContents();
                $data     = json_decode($contents, true);
                if ($data['error_code'] == 0) {
                    Log::info('百度回传成功：用户' . $type . '参数打印 用户ID-' . $message['user_id']);

                    return true;
                } else {
                    throw new \Exception('请求百度回传失败');
                }
            }
            Log::error('请求百度回传失败：用户' . $type . '参数打印 用户ID-' . $message['user_id']);

            return false;
        } catch (\Exception $exception) {
            Log::error('百度回传失败：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . '===>' . $exception->getMessage());

            return false;
        }
    }


    /**
     * VIVO回传
     *
     * @param $message
     * @param $callback
     * @param $type
     * @return bool
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public static function VivoReturn($message, $click, $type, $orderMoney = 0)
    {
        try {
            $client = new Client();
            $link   = PromotionLink::where('id', $click->promotion_link_id)->findOrEmpty();
            if ($link->isEmpty()) {
                throw new \Exception('推广链不存在');
            }
            $quickApp = Quickapp::where('id', $link->platform)->findOrEmpty();
            if ($quickApp->isEmpty()) {
                throw new \Exception('快应用不存在');
            }
            $pkgName = getPkgName($quickApp->package_name ?? '');
            if (!$pkgName) {
                throw new \Exception('快应用包名不存在');
            }

            $account = MediaAccount::where('promotion_link_id', $link->id)->where('media_id', Media::SOURCE_VIVO)->findOrEmpty();
            if ($account->isEmpty()) {
                throw new \Exception('推广账户不存在');
            }
            if (!($clientId = $account->auth_advertiser_id) || !($srcId = $account->src_id)) {
                throw new \Exception('未绑定VIVO事件源ID或授权应用ID');
            }
            $token      = (new VivoService($clientId))->getCacheToken($clientId);
            $event_time = msectime();
            $data       = [
                'srcType'  => 'Quickapp',
                'srcId'    => $srcId,
                'pkgName'  => $pkgName,
                'dataList' => [
                    'creativeId' => $click->creative_id ?? '',
                    'cvTime'     => $event_time,
                    'cvType'     => $type,
                    'requestId'  => $click->request_id ?? ''
                ]
            ];
            if ($type == self::VIVO_TYPE_PAYMENT) {
                array_push($data['dataList'], [
                    'exParam' => [
                        'payAmount' => $orderMoney * 100
                    ]
                ]);
            }
            $url = self::$vivoUrl
                . '?access_token=' . $token . '&timestamp=' . $event_time . '&nonce=' . md5($event_time . rand(1000, 9999));

            $result = $client->post($url, [
                'headers'            => self::$headers,
                'timeout'            => 60,
                RequestOptions::JSON => $data
            ]);
            if ($result->getStatusCode() == 200) {
                $contents = $result->getBody()->getContents();
                $data     = json_decode($contents, true);
                if ($data['code'] == 0) {
                    Log::write('VIVO回传成功：用户' . $type . '参数打印 用户ID-' . $message['user_id']);

                    return true;
                } else {
                    throw new \Exception('请求VIVO回传失败');
                }
            }

            return false;
        } catch (\Exception $exception) {
            Log::write('VIVO回传失败：用户' . $type . '参数打印 用户ID-' . $message['user_id'] . '===>' . $exception->getMessage());

            return false;
        }
    }
}
